home *** CD-ROM | disk | FTP | other *** search
/ MacHack 1996 / MacHack 1996.toast / Hacks / Hacks ’87 / Source ƒ.sit / Source ƒ / emacs source ƒ / EXEC.C < prev    next >
Encoding:
C/C++ Source or Header  |  1992-06-28  |  14.5 KB  |  768 lines  |  [TEXT/MARC]

  1. /*    This file is for functions dealing with execution of
  2.     commands, command lines, buffers, files and startup files
  3.  
  4.     written 1986 by Daniel Lawrence                */
  5.  
  6. #include    <stdio.h>
  7. #include    "estruct.h"
  8. #include    "edef.h"
  9.  
  10. /* namedcmd:    execute a named command even if it is not bound
  11. */
  12.  
  13. namedcmd(f, n)
  14.  
  15. int f, n;    /* command arguments [passed through to command executed] */
  16.  
  17. {
  18.     register (*kfunc)();    /* ptr to the requexted function to bind to */
  19.     int (*getname())();
  20.  
  21.     /* prompt the user to type a named command */
  22.     mlwrite(": ");
  23.  
  24.     /* and now get the function name to execute */
  25.     kfunc = getname();
  26.     if (kfunc == NULL) {
  27.         mlwrite("[No such function]");
  28.         return(FALSE);
  29.     }
  30.  
  31.     /* and then execute the command */
  32.     return((*kfunc)(f, n));
  33. }
  34.  
  35. /*    execcmd:    Execute a command line command to be typed in
  36.             by the user                    */
  37.  
  38. execcmd(f, n)
  39.  
  40. int f, n;    /* default Flag and Numeric argument */
  41.  
  42. {
  43.     register int status;        /* status return */
  44.     char cmdstr[NSTRING];        /* string holding command to execute */
  45.  
  46.     /* get the line wanted */
  47.     if ((status = mlreply(": ", cmdstr, NSTRING)) != TRUE)
  48.         return(status);
  49.  
  50.     return(docmd(cmdstr));
  51. }
  52.  
  53. /*    docmd:    take a passed string as a command line and translate
  54.         it to be executed as a command. This function will be
  55.         used by execute-command-line and by all source and
  56.         startup files. Lastflag/thisflag is also updated.
  57.  
  58.     format of the command line is:
  59.  
  60.         {# arg} <command-name> {<argument string(s)>}
  61.  
  62.     Macro storing is turned off by a line:
  63.  
  64.         [end]
  65.     or:
  66.         $end
  67.  
  68.     Execution return value will ALWAYS be passed back as true
  69.     if the line starts with:
  70.  
  71.         $force
  72.  
  73. */
  74.  
  75. docmd(cline)
  76.  
  77. char *cline;    /* command line to execute */
  78.  
  79. {
  80.     register char *tp;    /* pointer to current position in token */
  81.     register int f;        /* default argument flag */
  82.     register int n;        /* numeric repeat value */
  83.     register int i;
  84.     int sign;        /* sign of numeric argument */
  85.     int (*fnc)();        /* function to execute */
  86.     int status;        /* return status of function */
  87.     int oldcle;        /* old contents of clexec flag */
  88.     int llen;        /* length of cline */
  89.     int force;        /* force TRUE result? */
  90.     struct LINE *lp;    /* a line pointer */
  91.     char token[NSTRING];    /* next token off of command line */
  92.     int (*fncmatch())();
  93. #if    DEBUGM
  94.     char outline[NSTRING];
  95.  
  96.     /* if global SPELL mode is on, every line to execute
  97.        gets echo and a key needs to be pressed to continue
  98.        ^G will abort the command */
  99.     if (gmode & MDSPELL) {
  100.         strcpy(outline, "<<<");
  101.         strcat(outline, cline);
  102.         strcat(outline, ">>>");
  103.         mlwrite(outline);
  104.         update(TRUE);
  105.         if ((*term.t_getchar)() == 7) {
  106.             mlwrite("[Macro aborted]");
  107.             return(FALSE);
  108.         }
  109.     }
  110. #endif
  111.         
  112.     /* check to see if this line turns macro storage off */
  113.     if ((strcmp(cline, "[end]") == 0) ||
  114.         ((cline[0] == '$') && (cline[1] == 'e'))) {
  115.         mstore = FALSE;
  116.         bstore = NULL;
  117.         return(TRUE);
  118.     }
  119.  
  120.     /* check to see if we are going to force a TRUE result */
  121.     force = FALSE;
  122.     if ((cline[0] == '$') && (cline[1] == 'f'))
  123.         force = TRUE;
  124.     
  125.     /* if macro store is on, just salt this away */
  126.     if (mstore) {
  127.         /* trim leading indentation */
  128.         while (cline[0] == ' ' || cline[0] == '\t')
  129.             strcpy(cline, &cline[1]);
  130.  
  131.         /* allocate the space for the line */
  132.         llen = strlen(cline);
  133.         if ((lp=lalloc(llen)) == NULL) {
  134.             mlwrite("Out of memory while storing macro");
  135.             return (FALSE);
  136.         }
  137.  
  138.         /* copy the text into the new line */
  139.         for (i=0; i<llen; ++i)
  140.             lputc(lp, i, cline[i]);
  141.  
  142.         /* attach the line to the end of the buffer */
  143.                bstore->b_linep->l_bp->l_fp = lp;
  144.         lp->l_bp = bstore->b_linep->l_bp;
  145.         bstore->b_linep->l_bp = lp;
  146.         lp->l_fp = bstore->b_linep;
  147.         return (TRUE);
  148.     }
  149.     
  150.     /* first set up the default command values */
  151.     f = FALSE;
  152.     n = 1;
  153.     lastflag = thisflag;
  154.     thisflag = 0;
  155.  
  156.     strcpy(sarg, cline);    /* move string to string argument buffer */
  157.     if (force)        /* discard the $force */
  158.         nxtarg(token);
  159.     if ((status = nxtarg(token)) != TRUE)    /* and grab the first token */
  160.         return(status);
  161.  
  162.     /* check for and process numeric leadin argument */
  163.     if ((token[0] >= '0' && token[0] <= '9') || token[0] == '-') {
  164.         f = TRUE;
  165.         n = 0;
  166.         tp = &token[0];
  167.  
  168.         /* check for a sign! */
  169.         sign = 1;
  170.         if (*tp == '-') {
  171.             ++tp;
  172.             sign = -1;
  173.         }
  174.  
  175.         /* calc up the digits in the token string */
  176.         while(*tp) {
  177.             if (*tp >= '0' && *tp <= '9')
  178.                 n = n * 10 + *tp - '0';
  179.             ++tp;
  180.         }
  181.         n *= sign;    /* adjust for the sign */
  182.  
  183.         /* and now get the command to execute */
  184.         if ((status = nxtarg(token)) != TRUE)
  185.             return(status);        
  186.     }
  187.  
  188.     /* and match the token to see if it exists */
  189.     if ((fnc = fncmatch(token)) == NULL) {
  190.         mlwrite("[No such Function]");
  191.         return(FALSE);
  192.     }
  193.     
  194.     /* save the arguments and go execute the command */
  195.     oldcle = clexec;        /* save old clexec flag */
  196.     clexec = TRUE;            /* in cline execution */
  197.     status = (*fnc)(f, n);        /* call the function */
  198.     if (force)            /* force the status */
  199.         status = TRUE;
  200.     clexec = oldcle;        /* restore clexec flag */
  201.     return(status);
  202. }
  203.  
  204. /* gettok:    chop a token off a string
  205.         return a pointer past the token
  206. */
  207.  
  208. char *gettok(src, tok)
  209.  
  210. char *src, *tok;    /* source string, destination token string */
  211.  
  212. {
  213.     register int quotef;    /* is the current string quoted? */
  214.  
  215.     /* first scan past any whitespace in the source string */
  216.     while (*src == ' ' || *src == '\t')
  217.         ++src;
  218.  
  219.     /* if quoted, record it */
  220.     quotef = (*src == '"');
  221.     if (quotef)
  222.         ++src;
  223.  
  224.     /* scan through the source string */
  225.     while (*src) {
  226.         /* process special characters */
  227.         if (*src == '~') {
  228.             ++src;
  229.             if (*src == 0)
  230.                 break;
  231.             switch (*src++) {
  232.                 case 'r':    *tok++ = 13; break;
  233.                 case 'n':    *tok++ = 10; break;
  234.                 case 't':    *tok++ = 9;  break;
  235.                 case 'b':    *tok++ = 8;  break;
  236.                 case 'f':    *tok++ = 12; break;
  237.                 case '@':    *tok++ = 192;break;
  238.                 default:    *tok++ = *(src-1);
  239.             }
  240.         } else {
  241.             /* check for the end of the token */
  242.             if (quotef) {
  243.                 if (*src == '"')
  244.                     break;
  245.             } else {
  246.                 if (*src == ' ' || *src == '\t')
  247.                     break;
  248.             }
  249.  
  250.             /* record the character */
  251.             *tok++ = *src++;
  252.         }
  253.     }
  254.  
  255.     /* terminate the token and exit */
  256.     if (*src)
  257.         ++src;
  258.     *tok = 0;
  259.     return(src);
  260. }
  261.  
  262. /* nxtarg:    grab the next token out of sarg, return it, and
  263.         chop it of sarg                    */
  264.  
  265. nxtarg(tok)
  266.  
  267. char *tok;    /* buffer to put token into */
  268.  
  269. {
  270.     register char *newsarg;    /* pointer to new beginning of sarg */
  271.     register oldexec;    /* saved execution flag */
  272.     register BUFFER *bp;    /* ptr to buffer to get arg from */
  273.     register int status;
  274.     char *gettok();
  275.  
  276.     newsarg = gettok(sarg, tok);    /* grab the token */
  277.     strcpy(sarg, newsarg);        /* and chop it of sarg */
  278.  
  279.     /* check for an interactive argument */
  280.     if (*tok == '@') {        /* get interactive argument */
  281.         oldexec = clexec;    /* save execution flag */
  282.         clexec = FALSE;
  283.         status = mlreply(&tok[1], &tok[0], NSTRING);
  284.         clexec = oldexec;
  285.         if (status != TRUE)
  286.             return(status);
  287.     }
  288.  
  289.     /* check for a quoted "@" in the first position */
  290.     if (*tok == 192)
  291.         *tok = '@';
  292.  
  293.     /* check for an argument from a buffer */
  294.     if (*tok == '#') {
  295.  
  296.         /* get the referenced buffer */
  297.         bp = bfind(&tok[1], FALSE, 0);
  298.         if (bp == NULL)
  299.             return(FALSE);
  300.  
  301.         /* make sure we are not at the end */
  302.         if (bp->b_linep == bp->b_dotp)
  303.             return(FALSE);
  304.  
  305.         /* grab the line as an argument */
  306.         strncpy(tok, bp->b_dotp->l_text, bp->b_dotp->l_used);
  307.         tok[bp->b_dotp->l_used] = 0;
  308.  
  309.         /* and step the buffer's line ptr ahead a line */
  310.         bp->b_dotp = bp->b_dotp->l_fp;
  311.         bp->b_doto = 0;
  312.     }
  313.  
  314.     return(TRUE);
  315. }
  316.  
  317. /*    storemac:    Set up a macro buffer and flag to store all
  318.             executed command lines there            */
  319.  
  320. storemac(f, n)
  321.  
  322. int f;        /* default flag */
  323. int n;        /* macro number to use */
  324.  
  325. {
  326.     register struct BUFFER *bp;    /* pointer to macro buffer */
  327.     char bname[NBUFN];        /* name of buffer to use */
  328.  
  329.     /* must have a numeric argument to this function */
  330.     if (f == FALSE) {
  331.         mlwrite("No macro specified");
  332.         return(FALSE);
  333.     }
  334.  
  335.     /* range check the macro number */
  336.     if (n < 1 || n > 40) {
  337.         mlwrite("Macro number out of range");
  338.         return(FALSE);
  339.     }
  340.  
  341.     /* construct the macro buffer name */
  342.     strcpy(bname, "[Macro xx]");
  343.     bname[7] = '0' + (n / 10);
  344.     bname[8] = '0' + (n % 10);
  345.  
  346.     /* set up the new macro buffer */
  347.     if ((bp = bfind(bname, TRUE, BFINVS)) == NULL) {
  348.         mlwrite("Can not create macro");
  349.         return(FALSE);
  350.     }
  351.  
  352.     /* and make sure it is empty */
  353.     bclear(bp);
  354.  
  355.     /* and set the macro store pointers to it */
  356.     mstore = TRUE;
  357.     bstore = bp;
  358.     return(TRUE);
  359. }
  360.  
  361. /*    execbuf:    Execute the contents of a buffer of commands    */
  362.  
  363. execbuf(f, n)
  364.  
  365. int f, n;    /* default flag and numeric arg */
  366.  
  367. {
  368.         register BUFFER *bp;        /* ptr to buffer to execute */
  369.         register int status;        /* status return */
  370.         char bufn[NBUFN];        /* name of buffer to execute */
  371.  
  372.     /* find out what buffer the user wants to execute */
  373.         if ((status = mlreply("Execute buffer: ", bufn, NBUFN)) != TRUE)
  374.                 return(status);
  375.  
  376.     /* find the pointer to that buffer */
  377.         if ((bp=bfind(bufn, FALSE, 0)) == NULL) {
  378.         mlwrite("No such buffer");
  379.                 return(FALSE);
  380.         }
  381.  
  382.     /* and now execute it as asked */
  383.     while (n-- > 0)
  384.         if ((status = dobuf(bp)) != TRUE)
  385.             return(status);
  386.     return(TRUE);
  387. }
  388.  
  389. /*    dobuf:    execute the contents of the buffer pointed to
  390.         by the passed BP                */
  391.  
  392. dobuf(bp)
  393.  
  394. BUFFER *bp;    /* buffer to execute */
  395.  
  396. {
  397.         register int status;        /* status return */
  398.     register LINE *lp;        /* pointer to line to execute */
  399.     register LINE *hlp;        /* pointer to line header */
  400.     register int linlen;        /* length of line to execute */
  401.     register WINDOW *wp;        /* ptr to windows to scan */
  402.     char eline[NSTRING];        /* text of line to execute */
  403.  
  404.     /* starting at the beginning of the buffer */
  405.     hlp = bp->b_linep;
  406.     lp = hlp->l_fp;
  407.     while (lp != hlp) {
  408.         /* calculate the line length and make a local copy */
  409.         linlen = lp->l_used;
  410.         if (linlen > NSTRING - 1)
  411.             linlen = NSTRING - 1;
  412.         strncpy(eline, lp->l_text, linlen);
  413.         eline[linlen] = 0;    /* make sure it ends */
  414.  
  415.         /* if it is not a comment, execute it */
  416.         if (eline[0] != ';' && eline[0] != 0) {
  417.             status = docmd(eline);
  418.             if (status != TRUE) {    /* a command error */
  419.                 /* look if buffer is showing */
  420.                 wp = wheadp;
  421.                 while (wp != NULL) {
  422.                     if (wp->w_bufp == bp) {
  423.                         /* and point it */
  424.                         wp->w_dotp = lp;
  425.                         wp->w_doto = 0;
  426.                         wp->w_flag |= WFHARD;
  427.                     }
  428.                     wp = wp->w_wndp;
  429.                 }
  430.                 /* in any case set the buffer . */
  431.                 bp->b_dotp = lp;
  432.                 bp->b_doto = 0;
  433.                 return(status);
  434.             }
  435.         }
  436.         lp = lp->l_fp;        /* on to the next line */
  437.     }
  438.         return(TRUE);
  439. }
  440.  
  441. execfile(f, n)    /* execute a series of commands in a file
  442. */
  443.  
  444. int f, n;    /* default flag and numeric arg to pass on to file */
  445.  
  446. {
  447.     register int status;    /* return status of name query */
  448.     char *fname[NSTRING];    /* name of file to execute */
  449.  
  450.     if ((status = mlreply("File to execute: ", fname, NSTRING -1)) != TRUE)
  451.         return(status);
  452.  
  453.     /* otherwise, execute it */
  454.     while (n-- > 0)
  455.         if ((status=dofile(fname)) != TRUE)
  456.             return(status);
  457.  
  458.     return(TRUE);
  459. }
  460.  
  461. /*    dofile:    yank a file into a buffer and execute it
  462.         if there are no errors, delete the buffer on exit */
  463.  
  464. dofile(fname)
  465.  
  466. char *fname;    /* file name to execute */
  467.  
  468. {
  469.     register BUFFER *bp;    /* buffer to place file to exeute */
  470.     register BUFFER *cb;    /* temp to hold current buf while we read */
  471.     register int status;    /* results of various calls */
  472.     char bname[NBUFN];    /* name of buffer */
  473.  
  474.     makename(bname, fname);        /* derive the name of the buffer */
  475.     if ((bp = bfind(bname, TRUE, 0)) == NULL) /* get the needed buffer */
  476.         return(FALSE);
  477.  
  478.     bp->b_mode = MDVIEW;    /* mark the buffer as read only */
  479.     cb = curbp;        /* save the old buffer */
  480.     curbp = bp;        /* make this one current */
  481.     /* and try to read in the file to execute */
  482.     if ((status = readin(fname, FALSE)) != TRUE) {
  483.         curbp = cb;    /* restore the current buffer */
  484.         return(status);
  485.     }
  486.  
  487.     /* go execute it! */
  488.     curbp = cb;        /* restore the current buffer */
  489.     if ((status = dobuf(bp)) != TRUE)
  490.         return(status);
  491.  
  492.     /* if not displayed, remove the now unneeded buffer and exit */
  493.     if (bp->b_nwnd == 0)
  494.         zotbuf(bp);
  495.     return(TRUE);
  496. }
  497.  
  498. /*    cbuf:    Execute the contents of a numbered buffer    */
  499.  
  500. cbuf(f, n, bufnum)
  501.  
  502. int f, n;    /* default flag and numeric arg */
  503. int bufnum;    /* number of buffer to execute */
  504.  
  505. {
  506.         register BUFFER *bp;        /* ptr to buffer to execute */
  507.         register int status;        /* status return */
  508.     static char bufname[] = "[Macro xx]";
  509.  
  510.     /* make the buffer name */
  511.     bufname[7] = '0' + (bufnum / 10);
  512.     bufname[8] = '0' + (bufnum % 10);
  513.  
  514.     /* find the pointer to that buffer */
  515.         if ((bp=bfind(bufname, FALSE, 0)) == NULL) {
  516.             mlwrite("Macro not defined");
  517.                 return(FALSE);
  518.         }
  519.  
  520.     /* and now execute it as asked */
  521.     while (n-- > 0)
  522.         if ((status = dobuf(bp)) != TRUE)
  523.             return(status);
  524.     return(TRUE);
  525. }
  526.  
  527. cbuf1(f, n)
  528.  
  529. {
  530.     cbuf(f, n, 1);
  531. }
  532.  
  533. cbuf2(f, n)
  534.  
  535. {
  536.     cbuf(f, n, 2);
  537. }
  538.  
  539. cbuf3(f, n)
  540.  
  541. {
  542.     cbuf(f, n, 3);
  543. }
  544.  
  545. cbuf4(f, n)
  546.  
  547. {
  548.     cbuf(f, n, 4);
  549. }
  550.  
  551. cbuf5(f, n)
  552.  
  553. {
  554.     cbuf(f, n, 5);
  555. }
  556.  
  557. cbuf6(f, n)
  558.  
  559. {
  560.     cbuf(f, n, 6);
  561. }
  562.  
  563. cbuf7(f, n)
  564.  
  565. {
  566.     cbuf(f, n, 7);
  567. }
  568.  
  569. cbuf8(f, n)
  570.  
  571. {
  572.     cbuf(f, n, 8);
  573. }
  574.  
  575. cbuf9(f, n)
  576.  
  577. {
  578.     cbuf(f, n, 9);
  579. }
  580.  
  581. cbuf10(f, n)
  582.  
  583. {
  584.     cbuf(f, n, 10);
  585. }
  586.  
  587. cbuf11(f, n)
  588.  
  589. {
  590.     cbuf(f, n, 11);
  591. }
  592.  
  593. cbuf12(f, n)
  594.  
  595. {
  596.     cbuf(f, n, 12);
  597. }
  598.  
  599. cbuf13(f, n)
  600.  
  601. {
  602.     cbuf(f, n, 13);
  603. }
  604.  
  605. cbuf14(f, n)
  606.  
  607. {
  608.     cbuf(f, n, 14);
  609. }
  610.  
  611. cbuf15(f, n)
  612.  
  613. {
  614.     cbuf(f, n, 15);
  615. }
  616.  
  617. cbuf16(f, n)
  618.  
  619. {
  620.     cbuf(f, n, 16);
  621. }
  622.  
  623. cbuf17(f, n)
  624.  
  625. {
  626.     cbuf(f, n, 17);
  627. }
  628.  
  629. cbuf18(f, n)
  630.  
  631. {
  632.     cbuf(f, n, 18);
  633. }
  634.  
  635. cbuf19(f, n)
  636.  
  637. {
  638.     cbuf(f, n, 19);
  639. }
  640.  
  641. cbuf20(f, n)
  642.  
  643. {
  644.     cbuf(f, n, 20);
  645. }
  646.  
  647. cbuf21(f, n)
  648.  
  649. {
  650.     cbuf(f, n, 21);
  651. }
  652.  
  653. cbuf22(f, n)
  654.  
  655. {
  656.     cbuf(f, n, 22);
  657. }
  658.  
  659. cbuf23(f, n)
  660.  
  661. {
  662.     cbuf(f, n, 23);
  663. }
  664.  
  665. cbuf24(f, n)
  666.  
  667. {
  668.     cbuf(f, n, 24);
  669. }
  670.  
  671. cbuf25(f, n)
  672.  
  673. {
  674.     cbuf(f, n, 25);
  675. }
  676.  
  677. cbuf26(f, n)
  678.  
  679. {
  680.     cbuf(f, n, 26);
  681. }
  682.  
  683. cbuf27(f, n)
  684.  
  685. {
  686.     cbuf(f, n, 27);
  687. }
  688.  
  689. cbuf28(f, n)
  690.  
  691. {
  692.     cbuf(f, n, 28);
  693. }
  694.  
  695. cbuf29(f, n)
  696.  
  697. {
  698.     cbuf(f, n, 29);
  699. }
  700.  
  701. cbuf30(f, n)
  702.  
  703. {
  704.     cbuf(f, n, 30);
  705. }
  706.  
  707. cbuf31(f, n)
  708.  
  709. {
  710.     cbuf(f, n, 31);
  711. }
  712.  
  713. cbuf32(f, n)
  714.  
  715. {
  716.     cbuf(f, n, 32);
  717. }
  718.  
  719. cbuf33(f, n)
  720.  
  721. {
  722.     cbuf(f, n, 33);
  723. }
  724.  
  725. cbuf34(f, n)
  726.  
  727. {
  728.     cbuf(f, n, 34);
  729. }
  730.  
  731. cbuf35(f, n)
  732.  
  733. {
  734.     cbuf(f, n, 35);
  735. }
  736.  
  737. cbuf36(f, n)
  738.  
  739. {
  740.     cbuf(f, n, 36);
  741. }
  742.  
  743. cbuf37(f, n)
  744.  
  745. {
  746.     cbuf(f, n, 37);
  747. }
  748.  
  749. cbuf38(f, n)
  750.  
  751. {
  752.     cbuf(f, n, 38);
  753. }
  754.  
  755. cbuf39(f, n)
  756.  
  757. {
  758.     cbuf(f, n, 39);
  759. }
  760.  
  761. cbuf40(f, n)
  762.  
  763. {
  764.     cbuf(f, n, 40);
  765. }
  766.  
  767.  
  768.